import { useState ,useEffect ,useMemo } from 'react'
import { Modal, Form, Input, Select, message , Button} from 'antd'
import { useNavigate , useParams , useSearchParams} from 'react-router-dom'
import { useRequest } from 'ahooks'
import { typeList , addOrUpdateArticle , detailArticle } from '@/service/article'
import { detailGoal, updateContent } from '@/service/goal'
import { detailAbout , updateAbout } from '@/service/about'
import MDEditor from "@uiw/react-md-editor";
import "./index.less"

const { Option } = Select

type FromType = "article" | "goal" | 'about'

type ArticleProps = {
  isUpdate: boolean,
  onSubmit:(fun:(content:string , onSuccess:()=>void)=> void)=> void
}

function useArticle({isUpdate , onSubmit}:ArticleProps) {

  const [visible, setVisible] = useState<boolean>(false) // article
  const [ form ] = Form.useForm(); // article
  const { data: datalist = [] } = useRequest(typeList) // article

  useEffect(() => {  // article
    if (!visible && !isUpdate) {
      form.resetFields();
    }
  }, [visible]);


  const onArticleSubmit = async (content:string , onSuccess:()=> void) => {
    const params = form.getFieldsValue();
    await form.validateFields()
    const response = await addOrUpdateArticle({
      ...params,
      content,
    })
    
    if (response) {
      setVisible(false)
      message.success(`${isUpdate ? '更新' : '发布'}成功`);
      onSuccess()
    } else {
      message.error(`${ isUpdate ? '更新' : '发布'}失败，请重新尝试`)
    }
  }


  const modal = (
    <Modal
      title="发布"
      open={visible}
      onCancel={() => setVisible(false)}
      forceRender
      onOk={()=> onSubmit(onArticleSubmit)}
      bodyStyle={{paddingTop:'20px'}}
    >
      <Form
        layout="horizontal"
        form={form}
        size="small"
      >
        <Form.Item label="" name="id" style={{display:'none'}}>
          <Input max={50}/>
        </Form.Item>
        <Form.Item label="题目" name="title" rules={[{required :true , message:'必填'}]}>
          <Input placeholder="请输入文章题目" max={50}/>
        </Form.Item>
        <Form.Item label="描述" name="article_desc" rules={[{required :true,message:'必填'}]}>
          <Input placeholder="请输入文章描述" max={ 150 }/>
        </Form.Item>
        <Form.Item label="类型" name="article_type_id" rules={[{required :true ,message:'必填'}]}>
          <Select placeholder="请选择文章类型">
            {datalist.map(item => <Option value={item.id} key={item.id }>{ item.label }</Option> ) }
          </Select>
        </Form.Item>
        <Form.Item label="标签" name="tag">
          <Input placeholder="请输入文章标签" />
        </Form.Item>
        <Form.Item label="封面" name="pic">
          <Input placeholder="请上传文章封面" />
        </Form.Item>
      </Form>
    </Modal>
  )

  return {
    onMounted: (id:number ,onSuccess:(content:string)=> void) => {
      if (!isUpdate) return
      detailArticle({ id }).then(response => {
        const {
          content = "",
          id,
          article_desc,
          title,
          article_type_id,
          pic,
          tag
        } = response || {};
        form.setFieldsValue({
          id,
          article_desc,
          title,
          article_type_id,
          pic,
          tag
        });
        onSuccess(content)
      })
    },
    onSubmit: ()=> setVisible(true),
    extra:modal
  }
}

function useGoal() {
  return {
    onMounted: (id:number ,onData:(content:string)=> void ) => {
      detailGoal({ id }).then(response => {
        const { content = "" } = response || {};
        onData(content)
      })
    },
    onSubmit: async (id:number , content:string , onSuccess:()=> void) => {
      const response = await updateContent({ id, content : content || ""})
      if (response) {
        message.success("修改成功");
        onSuccess()
      } else {
        message.error(`修改失败，请重新尝试`)
      }
    }
  }
}

function useAbout() {
  return {
    onMounted: (id: number, onData: (content: string) => void )=>{
      detailAbout({ id }).then(response => {
        const { content = "" } = response || {};
        onData(content)
      })
    },
    onSubmit: async (id:number , content:string , onSuccess:()=> void) => {
      const response = await updateAbout({ id , content: content || ""})
      if (response) {
        message.success("修改成功");
        onSuccess()
      } else {
        message.error(`修改失败，请重新尝试`)
      }
    }
  }
}


export default function Edit() {

  const [content, setContent] = useState<string>(); // common
  const [searchParams] = useSearchParams();
  const fromType = searchParams.get("from") as FromType // common 
  const navigate = useNavigate(); // common
  const { id } = useParams<{ id: string }>();  // common
  const isUpdate = useMemo(() => (Number(id) !== -1), [id]);// common 

  const {
    onMounted: onArticleMounted,
    onSubmit: onArticleSubmit,
    extra,
  } = useArticle({
    isUpdate,
    onSubmit: (callback) => {
      callback(content || "", ()=> navigate("/admin/article"))
    }
  })

  const {
    onMounted: onGoalMounted,
    onSubmit: onGoalSubmit
  } = useGoal()

  const {
    onMounted: onAboutMounted,
    onSubmit: onAboutSubmit
  } = useAbout()

  // 初始化
  useEffect(() => {   // common 
    const $id = Number(id)
    const onSuccess = (content:string) => setContent(content)
    if (fromType === "article") {
      onArticleMounted($id, onSuccess)
    } else if (fromType === "goal") {
      onGoalMounted($id, onSuccess)
    } else {
      onAboutMounted($id , onSuccess)
    }
  },[])  

  // 提交
  const onSubmit = () => {  // common
    const $id = Number(id)
    const differentAction:Record<FromType , ()=>void > = {
      goal: ()=> onGoalSubmit($id, content || "" , ()=> navigate("/admin/goal") ),
      article: () => onArticleSubmit(),
      about:()=> onAboutSubmit($id , content || "" , ()=> navigate("/admin/about"))
    }
    differentAction[fromType]()
  }

  return (
    <div className="edit" data-color-mode="light">
      <Button size="small" onClick={onSubmit} style={{marginBottom:10}}>提交</Button>
      <MDEditor height={700} value={content || ""} onChange={setContent} />
      { extra }
    </div>
  )
}